<?php
/*
 * Copyright 2009 Chen Ze <http://chenze.name/>
 *
 *
 * @License BSD 
 *
 */

if (!class_exists('SJKObj')) {
class SJKObj {
    protected $table;
    protected $sjk;
    protected $enable_row_filter=false;
    public function __construct() {
    }
    public function __call($function,$args) {
        if (strpos($function,'selectOneBy')===0) {
            $field=strtolower(substr($function,11));
            $select_field=$args[1];
            return $this->selectOne(array($field=>$args[0]), $select_field);
        } else if (strpos($function,'selectRowBy')===0) {
            $field=strtolower(substr($function,11));
            if (!empty($args[1])) {
                $select_fields=$args[1];
            } else {
                $select_fields='*';
            }
            return $this->selectRow(array($field=>$args[0]), $select_fields);
        } else if (strpos($function,'selectSomeBy')===0) {
            $field=strtolower(substr($function,12));
            if (!empty($args[4])) {
                $select_fields=$args[4];
            } else {
                $select_fields='*';
            }
            if (!empty($args[3])) {
                $order=$args[3];
            } else {
                $order=null;
            }
            return $this->selectSome(array($field=>$args[0]), $args[1], $args[2], $order, $select_fields);
        } else if (strpos($function,'selectAllBy')===0) {
            $field=strtolower(substr($function,11));
            if (!empty($args[1])) {
                $select_fields=$args[1];
            } else {
                $select_fields='*';
            }
            if (!empty($args[3])) {
                $order=$args[3];
            } else {
                $order=null;
            }
            return $this->selectAll(array($field=>$args[0]), $order, $select_fields);
        } else if (strpos($function,'selectCountBy')===0) {
            $field=strtolower(substr($function,13));
            if (!empty($args[1])) {
                $select_fields=$args[1];
            } else {
                $select_fields='*';
            }
            return $this->selectCount(array($field=>$args[0]), $select_fields);
        }
    }
    public function selectAll($wheres=array(), $order=null, $select_fields='*') {
        if (!empty($order)) {
            $order=' ORDER BY '.$order;
        }
        $this->sjk->initSql('SELECT '.$select_fields.' FROM '.$this->table.
                            ' '.$this->buildWhere($wheres).$order);
        $rs=$this->sjk->query();
        if ($this->enable_row_filter) {
            $rows=$rs->fetchAll();
            foreach ($rows as $k=>$row) {
                $rows[$k]=$this->rowOutFilter($row);
            }
        } else {
            $rows=$rs->fetchAll();
        }
        return $rows;
    }
    public function selectSome($wheres, $offset, $limit, $order=null, $select_fields='*') {
        if (!empty($order)) {
            $order=' ORDER BY '.$order;
        }
        $offset=(int)$offset;
        $limit=(int)$limit;
        $this->sjk->initSql('SELECT '.$select_fields.' FROM '.$this->table.
                            ' '.$this->buildWhere($wheres).$order.' LIMIT '.$offset.','.$limit);
        $rs=$this->sjk->query();
        if ($this->enable_row_filter) {
            $rows=$rs->fetchAll();
            foreach ($rows as $k=>$row) {
                $rows[$k]=$this->rowOutFilter($row);
            }
        } else {
            $rows=$rs->fetchAll();
        }
        return $rows;
    }
    public function selectRow($wheres=array(), $select_fields='*', $order=null) {
        if (!empty($order)) {
            $order=' ORDER BY '.$order;
        }
        $this->sjk->initSql('SELECT '.$select_fields.' FROM '.$this->table.
                            ' '.$this->buildWhere($wheres).$order.' LIMIT 1');
        $rs=$this->sjk->query();
        if ($rs->num()>0) {
            $row=$rs->fetch();
            if ($this->enable_row_filter) {
                $row=$this->rowOutFilter($row);
            }
            return $row;
        } else {
            return false;
        }
    }
    public function selectOne($wheres=array(), $select_field, $order=null) {
        if (!empty($order)) {
            $order=' ORDER BY '.$order;
        }
        $this->sjk->initSql('SELECT '.$select_field.' as f FROM '.$this->table.
                            ' '.$this->buildWhere($wheres).$order.' LIMIT 1');
        $rs=$this->sjk->query();
        if ($rs->num()>0) {
            $row=$rs->fetch();
            if ($this->enable_row_filter) {
                $row=$this->rowOutFilter($row);
            }
            return $row['f'];
        } else {
            return false;
        }
    }
    public function count($wheres=array(), $select_fields='*') {
        $this->sjk->initSql('SELECT count('.$select_fields.') as c FROM '.$this->table.
                            ' '.$this->buildWhere($wheres));
        $rs=$this->sjk->query();
        $row=$rs->fetch();
        return $row['c'];
    }

    public function insert($data_arr) {
        if ($this->enable_row_filter) {
            $data_arr=$this->rowInFilter($data_arr);
        }
        $this->sjk->initSql('INSERT INTO '.$this->table.' #1');
        $this->sjk->setInsertArray(1, $data_arr);
        $this->sjk->query();
        return $this->sjk->getInsertId();
    }
    public function replace($data_arr) {
        if ($this->enable_row_filter) {
            $data_arr=$this->rowInFilter($data_arr);
        }
        $this->sjk->initSql('REPLACE INTO '.$this->table.' #1');
        $this->sjk->setInsertArray(1, $data_arr);
        return $this->sjk->query();
    }
    public function update($data_arr, $where_arr=array(), $limit=1) {
        if ($this->enable_row_filter) {
            $data_arr=$this->rowInFilter($data_arr);
        }
        if (empty($where_arr)) {
            $this->sjk->initSql('UPDATE '.$this->table.' SET #1');
        } else {
            $this->sjk->initSql('UPDATE '.$this->table.' SET #1 '.$this->buildWhere($where_arr));
        }
        if ($limit!==null) {
            $this->sjk->appendSql(' LIMIT '.$limit);
        }
        $this->sjk->setUpdateArray(1, $data_arr);
        return $this->sjk->query();
    }
    public function delete($where_arr=array(), $limit=1) {
        if (empty($where_arr)) {
            $this->sjk->initSql('DELETE FROM '.$this->table);
        } else {
            $this->sjk->initSql('DELETE FROM '.$this->table.' '.$this->buildWhere($where_arr));
        }
        if ($limit!==null) {
            $this->sjk->appendSql(' LIMIT '.$limit);
        }
        return $this->sjk->query();
    }

    public function getFields() {
        $this->sjk->initSql('DESC '.$this->table);
        $rs=$this->sjk->query();
        return $rs->fetchAll();
    }

    private function buildWhere($wheres) {
        if (!is_array($wheres)) {
            if (!empty($wheres)) {
                return ' WHERE '.$wheres;
            }
            return '';
        }
        $where='';
        foreach ($wheres as $field => $value) {
            if ($field=='_sjk_hardcode' || is_int($field)) {
            
                /*  
                    array(
                    '#1 AND #2 AND #3',
                    'value1','value2','value3', 
                    );
                */
                if (is_array($value)) {
                    $real_value=' '.current($value);
                    array_shift($value);
                    $i=1;
                    $hash='x'.time().'y';
                    $real_value=preg_replace('/#(\d{1,3})/','#'.$hash.'$1',$real_value);
                    foreach ($value as $value2) {
                        $this->sjk->setString($i,$value2);
                        $real_value=str_replace('#'.$hash.$i,"'".$this->sjk->escape($value2)."'",$real_value);
                        ++$i;
                    }
                    /*remove the hashes not replaced with the value*/
                    $real_value=str_replace($hash,'',$real_value);
                    if (is_int($field)) {
                        $where.=' AND '.$real_value;
                    } else {
                        $where.=' '.$real_value;
                    }
                } else {
                    if (is_int($field)) {
                        $where.=' AND '.$value;
                    } else {
                        $where.=' '.$value;
                    }
                }
            } else if (is_array($value)) {
                $where.=' AND `'.$field."` IN (";
                $cm='';
                foreach ($value as $value2) {
                    $where.=$cm."'".$this->sjk->escape($value2)."'";
                    $cm=',';
                }
                $where.=") ";
            } else {
                $where.=' AND `'.$field."`='".$this->sjk->escape($value)."' ";
            }
        }
        if (strlen($where)>0) {
            return ' WHERE '.substr(trim($where),3);
        } else {
            return '';
        }
    }
    protected function rowInFilter($row) {
        return $row;
    }
    protected function rowOutFilter($row) {
        return $row;
    }
}
}
